<!DOCTYPE html>
<meta charset="utf-8">
<title>service worker: Use Counter for intercepting requests from no-cors stylesheets</title>
<!-- Tests UseCounter for a service worker intercepting a request from a
     no-cors stylesheet. This cannot be upstreamed to WPT because it
     tests Chrome's UseCounter mechanism. -->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.js"></script>
<script src="/resources/get-host-info.js"></script>
<script>
function isUseCounted(win, feature) {
  return win.internals.isUseCounted(win.document, feature);
}

function observeUseCounter(win, feature) {
  return win.internals.observeUseCounter(win.document, feature);
}

function addStyleSheet(win, href) {
  const link = win.document.createElement('link');
  link.rel = 'stylesheet';
  link.href = href;
  win.document.head.appendChild(link);
}

// Use simple.html, not blank.html, since fonts are not loaded if there is no
// text.
const scope = 'resources/simple.html';
const basePath = new URL('.', self.location).pathname;
const remoteOrigin = get_host_info()['HTTP_REMOTE_ORIGIN'];
const remoteBase = new URL(basePath, remoteOrigin);

// The feature tested by this file,
// |kServiceWorkerInterceptedRequestFromOriginDirtyStyleSheet| from
// web_feature.mojom.
const kFeature = 2941;

// Loads a stylesheet that requests a subresource, and verifies that the
// feature use is counted when the stylesheet was not origin-clean.
function style_sheet_test(styleSheet, description) {
  promise_test(async t => {
    const remoteOriginStyleSheet =
        new URL(`resources/${styleSheet}`, remoteBase).href;

    // |frame1| uses a same-origin style sheet.
    const frame1 = await with_iframe('resources/simple.html');
    t.add_cleanup(() => { frame1.remove(); });
    const win1 = frame1.contentWindow;
    addStyleSheet(win1, styleSheet);

    // |frame2| is out-of-scope.
    const frame2 = await with_iframe('resources/other.html');
    t.add_cleanup(() => { frame2.remove(); });
    const win2 = frame2.contentWindow;
    addStyleSheet(win2, remoteOriginStyleSheet);

    // |frame3| uses a cross-origin style sheet.
    const frame3 = await with_iframe('resources/simple.html');
    t.add_cleanup(() => { frame3.remove(); });
    const win3 = frame3.contentWindow;
    addStyleSheet(win3, remoteOriginStyleSheet);

    // Only |frame3| should record the feature.
    await observeUseCounter(win3, kFeature);
    assert_false(isUseCounted(win1, kFeature));
    assert_false(isUseCounted(win2, kFeature));
    assert_true(isUseCounted(win3, kFeature));
  }, description);
}

promise_test(async t => {
  const registration = await service_worker_unregister_and_register(
      t, 'resources/network-fallback-worker.js', scope);
  await wait_for_state(t, registration.installing, 'activated');
}, 'global setup');

// Test a stylesheet that requests an image.
style_sheet_test('background-image.css', 'image');

// Test a stylesheet that requests an @import.
style_sheet_test('import.css', '@import');

// Test a stylesheet that requests a font.
style_sheet_test('font-face.css', 'font');

promise_test(async t => {
  return service_worker_unregister(t, scope);
}, 'cleanup');
</script>
